package kGeom;

public class kRange extends kElement {
	
	private kVec min;
	private kVec max;
	
	
	/*
	 * CONSTRUCTORS
	 * 
	 *  
	 * 
	 */
	
	public kRange(){
		min = new kVec();
		max = new kVec();
	}
	
	public kRange(kVec point){
		min = kVec.clone(point);
		max = kVec.clone(point);
	}
	
	/**
	 * REFERENCE CONSTRUCTOR
	 * 
	 */
	public kRange(kVec vec1, kVec vec2 ){
		min = new kVec( Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y), Math.min(vec1.z, vec2.z));
		max = new kVec( Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y), Math.max(vec1.z, vec2.z));
	}
	
	
	public kRange( float minX, float maxX, float minY , float maxY, float minZ, float maxZ ){
		this( new kVec(maxX,maxY,maxZ), new kVec(minX,minY,minZ) );
	}
	
	public kRange( float minVal , float maxVal  ) {
		this(maxVal, minVal, maxVal, minVal, maxVal, minVal);
	}
	
	public kRange( float val ) {
		this(val, -val, val, -val, val, -val);
	}
	
	public static kRange clone ( kRange range ) {return new kRange(kVec.clone(range.min),kVec.clone(range.max));}
	
	/*
	 * GETTERS AND SETTERS
	 * 
	 * 
	 * 
	 */
	
	public kVec minVec(){return kVec.clone(min);}
	public kVec maxVec(){return kVec.clone(max);}
	public float maxX(){ return max.x; }
	public float maxY(){ return max.y; }
	public float maxZ(){ return max.z; }
	public float minX(){ return min.x; }
	public float minY(){ return min.y; }
	public float minZ(){ return min.z; }
	public float deltX(){return maxX() - minX();}
	public float deltY(){return maxY() - minY();}
	public float deltZ(){return maxZ() - minZ();}
	public kVec[] cornerVecs(){
		kVec[] ret = new kVec[8];
		ret[0] = new kVec(min.x,min.y,min.z);
		ret[1] = new kVec(max.x,min.y,min.z);
		ret[2] = new kVec(min.x,max.y,min.z);
		ret[3] = new kVec(max.x,max.y,min.z);
		ret[4] = new kVec(min.x,min.y,max.z);
		ret[5] = new kVec(max.x,min.y,max.z);
		ret[6] = new kVec(min.x,max.y,max.z);
		ret[7] = new kVec(max.x,max.y,max.z);
		return ret;
	}
	
	public static kRange flipAxis(kRange range, int axisFlip){ return new kRange(kVec.flipAxis(range.min, axisFlip),kVec.flipAxis(range.max, axisFlip));}
	
	/*
	 * METHODS
	 * 
	 * 
	 * 
	 */
	
	/**
	 * width is x
	 */
	public float width(){return Math.abs(max.x - min.x);}
	
	/**
	 * height is y
	 */
	public float height(){return Math.abs(max.y - min.y);}
	
	/**
	 * depth is z
	 */
	public float depth(){return Math.abs(max.z - min.z);}
	
	public float area(){return width()*height()*depth();}
	
	public kVec center(){return new kVec( max.x - (width()/2) , max.y - (height()/2), max.z - (depth()/2) );}
	

	public void expandToPoint(kVec p){
		max.x = Math.max(max.x, p.x);
		max.y = Math.max(max.y, p.y);
		max.z = Math.max(max.z, p.z);
		
		min.x = Math.min(min.x, p.x);
		min.y = Math.min(min.y, p.y);
		min.z = Math.min(min.z, p.z);
	}
	
	public void combineWith(kRange range){
		max.x = Math.max(max.x, range.max.x);
		max.y = Math.max(max.y, range.min.y);
		max.z = Math.max(max.z, range.min.z);
		
		min.x = Math.min(min.x, range.min.x);
		min.y = Math.min(min.y, range.min.y);
		min.z = Math.min(min.z, range.min.z);
	}
	
	public void scale(float s){
		max.scale(s);
		min.scale(s);
	}
	public void scaleX(float s){max.scaleX(s);min.scaleX(s);}
	public void scaleY(float s){max.scaleY(s);min.scaleY(s);}
	public void scaleZ(float s){max.scaleZ(s);min.scaleZ(s);}
	
	public static kRange scale(kRange range, float s){
		kRange ret = kRange.clone(range);
		ret.scale(s);
		return ret;
	}
	
	public void translate(kVec vec){
		max.translate(vec);
	}
	
	public boolean containsPoint(kVec vec){
		if ( 
				(vec.x >= this.minX()) && (vec.x <= this.maxX()) && 
				(vec.y >= this.minY()) && (vec.y <= this.maxY()) && 
				(vec.z >= this.minZ()) && (vec.z <= this.maxZ())  
				)  return true;
		return false;
	}
	
	public String toString(){
		   return "["+min.x+"<"+max.x+","+deltX()+"]["+min.y+"<"+max.y+","+deltY()+"]["+min.z+"<"+max.z+","+deltZ()+"]";
		}
}
